package com.jack.thinking.thread.core._2;

import com.jack.thinking.thread.core._2.OutClass.InnerClass1;
import com.jack.thinking.thread.core._2.OutClass.InnerClass2;

/**
 * the same with Lock's 
 * @author wangbingwu
 *
 */
public class InnerStaticClass {
	public static void main(String[] args) {
		final InnerClass1 in1 = new InnerClass1();
		final InnerClass2 in2 = new InnerClass2();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				in1.method1(in2);
			}
		}, "T1");
		t1.start();
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				in1.method2();
			}
		}, "T2");
		t2.start();
		
		Thread t3 = new Thread(new Runnable() {
			@Override
			public void run() {
				in2.method1();
			}
		}, "T3");
		t3.start();
	}
}


class OutClass{
	static class InnerClass1{
		public void method1(InnerClass2 class2) {
			String threadName = Thread.currentThread().getName();
			synchronized (class2) {
				System.out.println(threadName + "enter InnerClass1's method1");
				for (int i = 0; i < 10; i++) {
					System.out.println("i=" + i);
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(threadName + "outer InnerClass1's method1");
			}
		}
		
		synchronized public void method2() {
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName + "enter InnerClass1's method2");
			for (int i = 0; i < 10; i++) {
				System.out.println("j=" + i);
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(threadName + "outer InnerClass1's method2");
		}
	}
	
	static class InnerClass2{
		synchronized public void method1() {
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName + "enter InnerClass2's method1");
			for (int i = 0; i < 10; i++) {
				System.out.println("k=" + i);
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(threadName + "outer InnerClass2's method1");
		}
	}
}